import logging

import neon.db_backend as db
import neon.atom as atom
import neon.guid as guid
import neon.version as version

l = logging.WARN
# l = logging.DEBUG
logging.basicConfig(level=l)

log = logging.getLogger('unit-test')

init = True
store_type = ':memory:'

backend = db.Sqlite(store_type, init)
backend.execute('CREATE TABLE tab1 (guid, id)')

class NeonDummy: pass
neon_dummy = NeonDummy()

neon_dummy.db_ = backend

atom_store = atom.AtomStore(neon_dummy, init, None)

# Register this type
t1 = atom.AtomType('testatom')
t1.add_table('tab1', ('SELECT guid FROM tab1 WHERE id = ?', ['id']))
atom_store.reg_type(t1)

try:
    assert atom_store.get_type('testatom')

    a = {}

    # Test single insert/integrate
    def ins(id, i, a, v = None):
        if v is None:
            v = version.from_raw('%s:%d' % (id, i))
        a[i] = atom.Atom(t1)
        a[i].set_guid(guid.from_raw('%s:%d' % (id, i)))
        a[i].set_version(v)
        a[i].fields = {'tab1' : [{'guid' : '%s:%d' % (id, i), 'id' : '5'}]}
        atom_store.put_atom(a[i])

    ins('test1', 1, a)
    tmp = atom_store.get_atom(guid.from_raw('test1:1'))
    assert tmp == a[1]

    for i in xrange(2, 100):
        ins('test1', i, a)
        for j in xrange(i - 1):
            tmp = atom_store.get_atom(guid.from_raw('test1:%d' % j))
            assert tmp is None
        tmp = atom_store.get_atom(guid.from_raw('test1:%d' % i))
        assert tmp == a[i]

    # Test delete
    b = {}
    ins('test2', 1, b)
    tmp = atom_store.get_atom(guid.from_raw('test2:1'))
    assert tmp == b[1]
    atom_store.del_atom(b[1])
    tmp = atom_store.get_atom(guid.from_raw('test2:1'))
    assert tmp is None

    # Test multiple integrate
    c = {}
    v1 = version.from_raw('test2.1:1')
    v3 = version.from_raw('test2.1:0 test2.2:1 test2.3:3')
    v2 = version.from_raw('test2.1:1 test2.2:2')

    assert v1 < v2
    assert v1 != v3
    assert v2 != v3
    
    ins('test2.1', 1, c, v1)
    ins('test2.3', 3, c, v3)
    ins('test2.2', 2, c, v2)

    tmp = atom_store.get_atom(guid.from_raw('test2.1:1'))
    assert tmp is None
    tmp = atom_store.get_atom(guid.from_raw('test2.2:2'))
    assert tmp == c[2]
    tmp = atom_store.get_atom(guid.from_raw('test2.3:3'))
    assert tmp == c[3]
    
except AssertionError:
    log.error('DEBUG DUMP --------------------------------------------------')
    backend.execute('SELECT * from neon_atom_meta')
    for i in backend.fetchall():
        log.error(i)
    raise
